package com.gdteam.kernel.domain.impl;

import java.util.Collection;
import java.util.List;

import javax.persistence.PersistenceException;

import org.apache.tapestry5.ioc.annotations.Inject;
import org.hibernate.Session;
import org.slf4j.Logger;

import com.gdteam.kernel.domain.Domain;
import com.gdteam.kernel.domain.DomainModelDAO;
import com.gdteam.kernel.domain.DomainModelFactory;

public class DomainModelDaoImpl<T> implements DomainModelDAO<T> {
    
	private Session session;
	private DomainModelFactory dmfactory = null;
	
	public final static String READ_ONLY_SEARCH_OPTION = "org.hibernate.readOnly";
	private Logger log;

	public DomainModelDaoImpl(Session session, @Inject DomainModelFactory dmfactory, Logger log) {
		this.session = session;
		this.dmfactory = dmfactory;
		this.log = log;
	}
	
	public Long count(String fqn) throws PersistenceException {
		return (Long) session.createQuery("select count(*) from " +dmfactory.get(fqn).getClass().getName()).uniqueResult();
	}
	
	public void save(Domain domain) throws PersistenceException {
		this.session.saveOrUpdate(domain);
	}
	
	public void update(Domain domain) throws PersistenceException {
		this.session.update(domain);
	}
	
	
	public void save(Collection<T> domains) throws PersistenceException {
		for (T dom : domains) {
			this.session.saveOrUpdate(dom);
		}
	}
	
	public void delete(Collection<T> domains) throws PersistenceException {
		for (T dom : domains) {
			this.session.delete(dom);
		}
	}
	
	public void delete(T domain) throws PersistenceException {
			this.session.delete(domain);
	}
	
	public void update(Collection<T> domains) throws PersistenceException {
		for (T dom : domains) {
			this.session.refresh(dom);
		}
	}
	
	public void deleteAll(String fqn) throws PersistenceException {
		List<T> objs = this.session.createQuery("from " + this.dmfactory.get(fqn).getClass().getName()).list();
		this.session.delete(objs);
		this.session.flush();
	}
	
	public Collection<T> getAll(String fqn) throws PersistenceException {		
		return (Collection<T>) this.session.createQuery("from " + this.dmfactory.get(fqn).getClass().getName()).list();
	}
	
	public Domain get(Class<T> class1, Long id, boolean readonly) {
		if (readonly) {
			return (null != id) ? (Domain) this.session.createQuery("from " + class1.getName() + " as c where c.id = :pk").setParameter("pk", id).setReadOnly(readonly).uniqueResult() : null;
		} else {
			return (null != id) ? (Domain)this.session.load(class1, id) : null;
		}
	}
	
}